﻿using BusinessResource;
using MongoDB.Bson;
using MongoDB.Driver;
using MongoDB.Driver.Builders;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Text;

namespace BusinessDB
{
    public interface IEntity
    {
        ObjectId Id { get; set; }
    }

    public abstract class EntityService<T> where T : IEntity
    {
        private MongoCollection<T> _collection;

        private MongoDBFacade _mf;

        private MongoDBFacade MF
        {
            get
            {
                if(_mf == null)
                    _mf = new MongoDBFacade(ServerConfig.Singleton.Database);
                return _mf;
            }
        }

        public MongoCollection<T> Collection
        {
            get
            {
                if(_collection == null)
                    _collection = MF.GetItems<T>(Key);
                return _collection;
            }
        }

        protected abstract string Key {get;}

        public IList<T> GetItems()
        {
            List<T> list = new List<T>();
            list.AddRange(Collection.FindAll());
            return list;
        }

        public T Find(short id)
        {
            var query = Query<T>.EQ(e => e.Id.Pid, id);
            return Collection.FindOne(query);
        }

        public short Add(T t)
        {
            Collection.Insert(t);
            return t.Id.Pid;
        }

        public bool Update(T t)
        {
            var query = Query<T>.EQ(e => e.Id.Pid, t.Id.Pid);
            T source = Collection.FindOne(query);
            Collection.Remove(query);

            bool result = Collection.Insert(t).Ok;
            if(!result)
                Collection.Insert(source);
            return result;
        }

        public bool Delete(short id)
        {
            var query = Query<T>.EQ(e => e.Id.Pid, id);
            return Collection.Remove(query).Ok;
        }

        public void Clear()
        {
            Collection.RemoveAll();
        }

        public bool Exists()
        {
            return MF.CollectionExists(Key);
        }
    }

    public class UserService : EntityService<UserDB>
    {
        protected override string Key
        {
            get { return "UserDB"; }
        }

        public UserDB Find(string name)
        {
            var query = Query<UserDB>.EQ(r => r.Name, name);
            return Collection.FindOne(query);
        }
    }

    public class ProdService : EntityService<ProdDB>
    {
        protected override string Key
        {
            get { return "ProdDB"; }
        }
    }

    public class ResourceService : EntityService<ResItemDB>
    {
        protected override string Key
        {
            get { return "ResItemDB"; }
        }
    }
}
